//-------------------------------------------------------
// Copyright 
// All rights reserved.
//
// File Name: LinkNode.h
// File Des: 链表封装
// File Summary:
// Cur Version: 1.0
// Author:
// Create Data:
// History:
// 		<Author>	<Time>		<Version>	  <Des>
//      lzlong	2024-1-31	1.0
//-------------------------------------------------------
#pragma once

/// <summary>
///		统一的链表封装
/// </summary>
template <class TObj> class CLinkNodeT {
public:
    CLinkNodeT() {
        m_pPrev = NULL;                               // Thre previous node is NULL
        m_pNext = sm_pHead;                           // The next node was at the head
        sm_pHead = (TObj*)this;                       // This node is now at the head
        if (m_pNext) m_pNext->m_pPrev = sm_pHead;     // The next node previous node was at the head
    }
    virtual ~CLinkNodeT() {
        TObj* p = sm_pHead;
        if (p == this) {     // Removing the head node
            sm_pHead = p->m_pNext;
        }
        else {
            BOOL bFound = FALSE;
            // Walk list from head and fix pointers
            for (; !bFound && (p->m_pNext != NULL); p = p->m_pNext) {
                if (p->m_pNext == this) {
                    // Make the node that points to us point to our next node
                    p->m_pNext = p->m_pNext->m_pNext;
                    bFound = TRUE;
                }
            }
        }
        m_pPrev = NULL;            // reset
        m_pNext = NULL;            // reset
    }

    /// -------------------------------------------------
    /// @brief 获取头结点
    /// @return 头结点指针
    static TObj* GetHeadNode() {
        return sm_pHead;
    }

    /// -------------------------------------------------
    /// @brief 获取下一个节点的指针
    /// @return 下一个节点的指针
    TObj* GetNextNode() const {
        return m_pNext;
    }

    /// -------------------------------------------------
    /// @brief 获取上一个节点的指针
    /// @return 上一个节点的指针
    TObj* GetPrevNode() const {
        return m_pPrev;
    }

protected:
    /// <summary>
    /// < Address of first object
    /// </summary>
    static TObj* sm_pHead;

    /// <summary>
    /// < Address of next object
    /// </summary>
    TObj* m_pNext;

    /// <summary>
    /// < Address of previous object
    /// </summary>
    TObj* m_pPrev;
};

template <class TObj>
TObj* CLinkNodeT<TObj>::sm_pHead = NULL;